package com.thoughtworks.bytecode2class.tools;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class FileInHex {

    private static String userage =
            "java com.thoughtworks.bytecode2class.tools.FileInHex <classFile>";

    private static int itemsPerLine = 16;

    public static void main(String[] args) {
        if (args.length != 1) {
            System.err.println(userage);
            return;
        }

        String classFile = args[0];//"/home/isaachan/Desktop/CharQueue.class";
        try {
            List<Byte> bytes = buildByteArray(new FileInputStream(classFile));
            List<String> hexes = new LinkedList<String>();
            for (Byte aByte : bytes) {
                hexes.add(convertByteToHexString(aByte));
            }

            printHex(hexes);
        } catch (FileNotFoundException e) {
            System.err.printf("File %s is not exist.", classFile);
        } catch (IOException e) {
            System.err.printf("Error orrcud during reading file %s.", classFile);
        }
    }

    private static void printHex(List<String> hexes) {
        int itemsInThisLine = 0;
        for (String hex : hexes) {
            System.out.print(hex + " ");
            itemsInThisLine++;
            if (itemsInThisLine == itemsPerLine) {
                System.out.println();
                itemsInThisLine = 0;
            }
        }
    }

    private static String convertByteToHexString(byte b) {
        String convert = Integer.toHexString(b);
        if (convert.length() == 1) convert = "0" + convert;
        if (convert.length() == 8) convert = convert.substring(6);
        return convert.toUpperCase();
    }

    private static List<Byte> buildByteArray(InputStream in) throws IOException {
        ArrayList<Byte> bytes = new ArrayList<Byte>();
        int i;
        while ((i = in.read()) != -1) {
            bytes.add((byte) i);
        }
        return bytes;
    }
}
